package org.mics.enduser.controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.mics.cache.redis.RedisHelper;
import org.mics.core.model.CurrentUser;
import org.mics.core.response.OneDataResponse;
import org.mics.core.response.SimpleResponse;
import org.mics.email.service.EmailCodeService;
import org.mics.enduser.entity.EndUserDO;
import org.mics.enduser.request.ForgetRequest;
import org.mics.enduser.request.LoginRequest;
import org.mics.enduser.request.RegisterRequest;
import org.mics.enduser.request.SLoginRequest;
import org.mics.enduser.service.EndUserService;
import org.mics.enduser.service.LoginLogService;
import org.mics.enduser.vo.EndUserTokenVO;
import org.mics.enduser.vo.EndUserVO;
import org.mics.lang.bean.BeanConvertUtil;
import org.mics.token.annotation.IgnoreToken;
import org.mics.token.annotation.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 终端用户
 * @author mics
 * @date 2020年6月10日
 * @version  1.0
 */
@RestController
@RequestMapping("/endUser")
@Tag(name = "[客户端]-用户")
public class EndUserController {
	@Resource
	private EndUserService endUserService;
	@Resource
	private EmailCodeService emailCodeService;
	@Resource
	private LoginLogService loginLogService;
	@Resource
	private RedisHelper redisHelper;
	private static final Logger LOGGER = LoggerFactory.getLogger(EndUserController.class);
	
	
	@IgnoreToken
    @Operation(summary =  "用户注册")
	@PostMapping("/register")
	public OneDataResponse<EndUserTokenVO> register(@Validated @RequestBody  RegisterRequest registerRequest,HttpServletResponse response) {
		LOGGER.info("用户注册[account:{}]", registerRequest.getAccount());
		EndUserDO entity = endUserService.register(registerRequest);
		LOGGER.info("用户注册成功[account:{}]", entity.getAccount());
		LoginRequest loginRequest = BeanConvertUtil.convert(registerRequest, LoginRequest.class);
		EndUserTokenVO endUserTokenVO = endUserService.login(loginRequest);
		LOGGER.debug("账号密码登录成功");
		LOGGER.info("用户登录成功[account:{}]", entity.getAccount());
        return new OneDataResponse<>(endUserTokenVO);
	}
	
    @Operation(summary =  "账号+密码登录")
	@IgnoreToken
    @PostMapping("/login")
	public OneDataResponse<EndUserTokenVO> login(@Validated @RequestBody LoginRequest loginRequest,HttpServletRequest request,HttpServletResponse response) {
		LOGGER.info("账号密码登录[account:{}]", loginRequest.getAccount());
		EndUserTokenVO endUserTokenVO = endUserService.login(loginRequest);
		LOGGER.debug("账号密码登录成功");
		return new OneDataResponse<EndUserTokenVO>(endUserTokenVO);
	}
    
    
    
    @Operation(summary =  "账号+验证码登录")
	@IgnoreToken
    @PostMapping("/slogin")
	public OneDataResponse<EndUserTokenVO> slogin(@Validated @RequestBody SLoginRequest sLoginRequest) {
		LOGGER.info("账号验证码登录[account:{}]", sLoginRequest.getAccount());
		EndUserTokenVO endUserTokenVO = endUserService.slogin(sLoginRequest);
		LOGGER.debug("账号验证码登录成功");
		return new OneDataResponse<EndUserTokenVO>(endUserTokenVO);
	}
	
	
    @Operation(summary =  "获取用户信息")
    @GetMapping("/info")
    public OneDataResponse<EndUserVO> info(@LoginUser CurrentUser currentUser) {
    	EndUserDO endUserDO = endUserService.info(currentUser.getId());
        LOGGER.debug("根据token获取用户信息成功");
        return new OneDataResponse<EndUserVO>(BeanConvertUtil.convert(endUserDO, EndUserVO.class));
    }
    
	
	@IgnoreToken
    @Operation(summary =  "忘记密码")
    @PostMapping("/forget")
    public SimpleResponse forget(@Validated @RequestBody ForgetRequest forgetRequest) {
		LOGGER.info("重置密码[account:{}]", forgetRequest.getAccount());
        endUserService.forget(forgetRequest);
        LOGGER.debug("重置密码成功"); 
        return new SimpleResponse();
    }
	
	
	@Operation(summary =  "根据id获取用户信息")
    @RequestMapping(value = "/findById/{id}",method = RequestMethod.GET)
    public EndUserVO findById(@PathVariable("id")String id) {
    	EndUserDO endUserDO = endUserService.info(id);
        LOGGER.debug("根据token获取用户信息成功");
        return BeanConvertUtil.convert(endUserDO, EndUserVO.class);
    }
    
    @Operation(summary =  "根据id删除用户信息")
    @RequestMapping(value = "/deleteById/{id}",method = RequestMethod.DELETE)
    public SimpleResponse deleteById(@PathVariable("id")String id) {
    	endUserService.deleteById(id);
        LOGGER.debug("删除用户信息成功[用户id:{}]",id);
        return new SimpleResponse();
    }
    
	@Operation(summary =  "根据账号查询用户信息")
    @RequestMapping(value = "/findByAccount/{account}",method = RequestMethod.GET)
    public EndUserVO findByAccount(@PathVariable("account")String account) {
    	EndUserDO endUserDO = endUserService.findByAccount(account);
        LOGGER.debug("根据账号查询用户信息成功[用户id:{}]",account);
        return BeanConvertUtil.convert(endUserDO, EndUserVO.class);
    } 
	
	@Operation(summary =  "创建用户")
    @RequestMapping(value = "/createUser",method = RequestMethod.POST)
	public String createUser(@RequestBody EndUserDO endUserDO) {
		String id =   endUserService.createUser(endUserDO);
		return id;
	}
	
	@Operation(summary =  "退出登录")
    @RequestMapping(value = "/logout",method = RequestMethod.GET)
	public SimpleResponse logout(@LoginUser CurrentUser currentUser,HttpServletRequest request,HttpServletResponse response) {
		//清除登录状态
		String token = currentUser.getToken();
		//存储登录信息
        redisHelper.del(token);
		return new SimpleResponse();
	}
	
	
	@Operation(summary =  "登录次数")
    @RequestMapping(value = "/loginNumber",method = RequestMethod.GET)
	public OneDataResponse<Integer> loginNumber(@LoginUser CurrentUser currentUser){
		Integer number = loginLogService.loginNumber(currentUser.getId());
		return new OneDataResponse<Integer>(number);
	}
}
